#!/usr/bin/with-contenv bashio
# vim: ft=bash
# shellcheck shell=bash
# ==============================================================================
# Start universal-silabs-flasher
# ==============================================================================

set -e

# shellcheck disable=SC2034
declare autoflash_firmware
declare device
declare bootloader_baudrate
declare firmware
declare verbose
declare usb_device_path
declare usb_manufacturer
declare usb_product
declare gpio_reset_flag
declare exit_status

function cleanup() {
    exit_status=$?
    bashio::log.info "universal-silabs-flasher-up script exited with code ${exit_status}"
    echo "${exit_status}" > /run/s6-linux-init-container-results/exitcode

    /run/s6/basedir/bin/halt
}
trap cleanup EXIT

function exit_no_firmware {
    bashio::log.warning "No firmware found for the selected device, assuming firmware is installed."
    exit 0
}

# Function to check if the device is Home Assistant Yellow
function is_home_assistant_yellow {
    # First, ensure the device is /dev/ttyAMA1
    if [ "${device}" != "/dev/ttyAMA1" ]; then
        return 1
    fi

    # Check the known paths for Home Assistant Yellow
    local paths=(
        "/sys/devices/platform/soc/fe201800.serial/tty/ttyAMA1"
        "/sys/devices/platform/axi/1000120000.pcie/1f0003c000.serial/tty/ttyAMA1"
    )
    for path in "${paths[@]}"; do
        if [ -d "${path}" ]; then
            return 0
        fi
    done
    return 1
}

device=$(bashio::config 'device')
bootloader_baudrate=$(bashio::config 'bootloader_baudrate')

if is_home_assistant_yellow; then
    bashio::log.info "Detected Home Assistant Yellow"
    gpio_reset_flag="--bootloader-reset yellow"
else
    gpio_reset_flag=""
fi

if bashio::config.has_value 'firmware_url'; then
    curl --silent -L -o "/root/firmware.gbl" "$(bashio::config 'firmware_url')"
    if [ ! -f "/root/firmware.gbl" ]; then
        bashio::log.warning "Downloading firmware failed"
        exit 0
    fi

    firmware="firmware.gbl"
else
    # Assume to run on Yellow if UART4 is mapped to ttyAMA1
    if is_home_assistant_yellow; then
        firmware="yellow_zigbee_ncp_7.4.4.0.gbl"
    else
        # Check device manufacturer/product information
        # shellcheck disable=SC2046,SC2086
        usb_device_path=$(realpath /sys/class/tty/$(readlink /sys/class/tty/$(basename ${device}) | sed 's:/[^/]*tty[^/]*::g' )/../)
        if [ ! -f "${usb_device_path}/idProduct" ]; then
            bashio::log.info "The selected serial port is not a USB device."
            exit_no_firmware
        fi

        if [ ! -f "${usb_device_path}/manufacturer" ] || [ ! -f "${usb_device_path}/product" ]; then
            bashio::log.info "USB device is missing manufacturer or product name."
            exit_no_firmware
        fi

        usb_manufacturer=$(cat "${usb_device_path}/manufacturer")
        usb_product=$(cat "${usb_device_path}/product")

        bashio::log.info "Checking ${device} identifying ${usb_product} from ${usb_manufacturer}."
        if [[ "${usb_manufacturer}" == "Nabu Casa" && "${usb_product}" == "SkyConnect"* ]]; then
            firmware="skyconnect_zigbee_ncp_7.4.4.0.gbl"
        elif [[ "${usb_manufacturer}" == "Nabu Casa" && "${usb_product}" == "Home Assistant Connect ZBT-1"* ]]; then
            firmware="skyconnect_zigbee_ncp_7.4.4.0.gbl"
        else
            exit_no_firmware
        fi
        gpio_reset_flag=""
    fi
fi

verbose=""
if bashio::config.true 'verbose'; then
    verbose="-v"
fi

declare -a ezsp_baudrate_arg=()
if bashio::config.has_value 'ezsp_baudrate'; then
    baud="$(bashio::config 'ezsp_baudrate')"
    ezsp_baudrate_arg=(--ezsp-baudrate "$baud")
fi

bashio::log.info "Starting universal-silabs-flasher with ${device} (bootloader baudrate ${bootloader_baudrate})"
# shellcheck disable=SC2086
universal-silabs-flasher \
    ${verbose} \
    --device ${device} \
    --bootloader-baudrate "${bootloader_baudrate}" \
    "${ezsp_baudrate_arg[@]}" \
    ${gpio_reset_flag} \
    flash --force --firmware "/root/${firmware}"
